<!DOCTYPE html>
<body>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="resources/gamepad-helpers.js"></script>
<script>

function checkVibrationActuatorOnDisconnect() {
  return new Promise(resolve => {
    window.addEventListener('gamepaddisconnected', (e) => {
        // The vibration actuator member should be null for a disconnected
        // gamepad.
        assert_equals(e.gamepad.vibrationActuator, null);
        resolve();
    }, { once: true });
  });
}

promise_test(async (t) => {
    // Connect a gamepad with no vibration actuator.
    let connectPromise = ongamepadconnected(t);
    gamepadController.connect(0);
    gamepadController.setId(0, "ZEROAXIS");
    gamepadController.setDualRumbleVibrationActuator(0, false);
    gamepadController.dispatchConnected(0);
    await connectPromise;

    let gamepad = navigator.getGamepads()[0];
    assert_equals(gamepad.vibrationActuator, null);
}, "null vibration actuator is null");

promise_test(async (t) => {
    // Connect a gamepad with a dual-rumble vibration actuator.
    let connectPromise = ongamepadconnected(t);
    gamepadController.connect(0);
    gamepadController.setId(0, "DullShark Rumble");
    gamepadController.setDualRumbleVibrationActuator(0, true);
    gamepadController.dispatchConnected(0);
    await connectPromise;

    let gamepad = navigator.getGamepads()[0];
    assert_equals(gamepad.vibrationActuator.__proto__,
                  GamepadHapticActuator.prototype);
    assert_equals(gamepad.vibrationActuator.type.__proto__,
                  String.prototype);
    assert_equals(gamepad.vibrationActuator.type, 'dual-rumble');
    assert_equals(gamepad.vibrationActuator.playEffect.__proto__,
                  Function.prototype);
    assert_equals(gamepad.vibrationActuator.reset.__proto__,
                  Function.prototype);
}, "validate gamepad haptic actuator API");

promise_test(async (t) => {
    // Connect a gamepad with a dual-rumble vibration actuator.
    let connectPromise = ongamepadconnected(t);
    gamepadController.connect(0);
    gamepadController.setId(0, "Checkbox Elite");
    gamepadController.setDualRumbleVibrationActuator(0, true);
    gamepadController.dispatchConnected(0);
    await connectPromise;

    let gamepad = navigator.getGamepads()[0];
    assert_equals(gamepad.vibrationActuator, gamepad.vibrationActuator);
}, "vibration actuator is same object");

promise_test(async (t) => {
    // Connect a gamepad with a dual-rumble vibration actuator.
    let connectPromise = ongamepadconnected(t);
    gamepadController.connect(0);
    gamepadController.setId(0, "Ipswich Pro");
    gamepadController.setButtonCount(0, 1);
    gamepadController.setDualRumbleVibrationActuator(0, true);
    gamepadController.dispatchConnected(0);
    await connectPromise;

    let gamepadBefore = navigator.getGamepads()[0];

    // Press button 0.
    gamepadController.setButtonData(0, 0, 1);

    let gamepadAfter = navigator.getGamepads()[0];
    assert_equals(gamepadAfter.buttons[0].value, 1.0);

    assert_equals(gamepadBefore.vibrationActuator,
                  gamepadAfter.vibrationActuator);
}, "vibration actuator is still the same object after a button press");

promise_test(async (t) => {
    // Connect a gamepad with a dual-rumble vibration actuator.
    let connectPromise = ongamepadconnected(t);
    gamepadController.connect(0);
    gamepadController.setId(0, "Nintendto Experiment");
    gamepadController.setDualRumbleVibrationActuator(0, true);
    gamepadController.dispatchConnected(0);
    await connectPromise;

    let actuatorBefore = navigator.getGamepads()[0].vibrationActuator;

    // Disconnect the gamepad and connect a different one, also with vibration.
    connectPromise = ongamepadconnected(t);
    gamepadController.disconnect(0);
    gamepadController.connect(0);
    gamepadController.setId(0, "Nintendto Implement");
    gamepadController.setDualRumbleVibrationActuator(0, true);
    gamepadController.dispatchConnected(0);
    await connectPromise;

    let gamepadAfter = navigator.getGamepads()[0];
    let actuatorAfter = gamepadAfter.vibrationActuator;

    assert_equals(gamepadAfter.id, "Nintendto Implement");
    assert_not_equals(actuatorBefore, actuatorAfter);
}, "vibration actuator is different for different gamepad");

promise_test(async (t) => {
    // Connect a gamepad with a dual-rumble vibration actuator.
    let connectPromise = ongamepadconnected(t);
    gamepadController.connect(0);
    gamepadController.setId(0, "Nintendto Ship");
    gamepadController.setDualRumbleVibrationActuator(0, true);
    gamepadController.dispatchConnected(0);
    await connectPromise;

    // Disconnect the gamepad.
    let disconnectPromise = checkVibrationActuatorOnDisconnect();
    gamepadController.disconnect(0);
    await disconnectPromise;
}, "vibration actuator is null for disconnected gamepad");

</script>
</body>
